class: center, middle, inverse, title-slide .title[ # From a Script to a Function ] .subtitle[ ## Illustration with plotting funtion ] .date[ ###
] --- # Learning objectives Creating functions, a first step into R programming * Understand Why Functions are needed * Learn to transition from Scripts to Functions * Call Custom Function * Function Documentation --- ## Why transitionning from Scripts to Functions? __Code Re-usability__ * Functions allow you to reuse code. * Write a function once and use it multiple times. __Modularity__ * Functions help in breaking down complex tasks into smaller, manageable pieces. * Easier to debug and maintain. * First step into building package and then creating a webinterface for less-technical users to re-use your work... __Collaboration__ * Functions make it easier to collaborate with others. * Share functions instead of long scripts. --- ## In appearance, it can be very similar... .pull-left[ An Example of a __Script__ ```r # calculate the mean of a numeric vector # Data example data <- c(1, 2, 3, 4, 5) # Apply mean to data mean_value <- mean(data) # Display the result print(mean_value) ``` ``` ## [1] 3 ``` ] .pull-right[ An Example of a __Function__ ```r # Smae: calculate the mean of a numeric vector calculate_mean <- function(data) { mean_value <- mean(data) return(mean_value) } # Data example data <- c(1, 2, 3, 4, 5) # Apply mean to data mean_value <- calculate_mean(data) # Display the result print(mean_value) ``` ``` ## [1] 3 ``` ] --- ## Though, there are Key Differences .pull-left[ A script is a file containing a series of R commands that can be executed in sequence. A function is a block of code that performs a specific task and can be called from other parts of the code. A script is executed as a series of commands, while a function is executed when it is called by other parts of the code: in other words, functions __encapsulate__ code into reusable units. Parameters allow customization of function behavior, this means you can get your function to __scale up__ to different context, which makes your ] .pull-right[ ```r # Function Structure function_name <- function(parameter1, parameter2, ...) { # Function body # Perform operations return(result) } ``` ] --- ## Example: Custom Function Let's see the steps in details: ```r # Custom function to calculate the median of a numeric vector calculate_median <- function(data) { # 1. Takes an input: here data... median_value <- median(data) # 2. Apply a transformation: here apply another function called median return(median_value) # 3. Generates an output defined with return() } ``` --- ## Why Document Functions? * Documentation provides information on how to use a function. * Helps other users (__including your future self!__) understand the purpose and usage of the function. * Standard practice for sharing code. What should I care about when doing it? * Always include an example with dummy data to demonstrate your function and it behavior * Follow modern and consistent code formatting. * Make sure to leave space correctly between each parts of your code * Use tools like styler for code formatting. What shall I used to do it? * Use roxygen2 or devtools for generating R documentation. * Add details about parameters, return values, and examples. --- ## Example Documentation ```r #' Calculate the median of a numeric vector. #' #' This function takes a numeric vector and returns its median value. #' #' @param data A numeric vector. #' #' @return The median of the input vector. #' #' @examples #' data <- c(1, 2, 3, 4, 5) #' median_value <- calculate_median(data) #' #' @export calculate_median <- function(data) { median_value <- median(data) return(median_value) } ``` --- ## Example: Recurrent chart .pull-left[ You likely have a recurrent plots that are used multiple times or needs to be updated every year. ```r refugees::population |> filter(year == 2022 & coa_name == "Peru") |> summarise(refugees = sum(refugees, na.rm = TRUE) + sum(oip, na.rm = TRUE), .by = coo_name ) |> slice_max(order_by = refugees, n = 10) |> mutate(coo_name = str_wrap(coo_name, 25)) |> ggplot( aes( x = refugees, y = reorder(coo_name, refugees))) + geom_col( fill = unhcr_pal(n = 1, "pal_blue"), width = 0.8) + scale_x_continuous( expand = expansion(mult = c(0, .1)), breaks = seq(0, 7e6, by = 1e6), labels = scales::label_number(scale_cut = scales::cut_short_scale())) + labs( title = "Refugees and other people in need of international protection in Peru", subtitle = "By country of origin at the end of 2022", caption = "Source: Refugee Data Finder<br>© UNHCR, The UN Refugee Agency", x = "Number of people" ) + theme_unhcr(grid = "X", axis = "Y", axis_title = "X") ``` ] .pull-right[ <!-- --> ] --- ## How to update my scripts In order to update my scripts, I will need to update the filters and the label ```r refugees::population |> * filter(year == 2022 & * coa_name == "Peru") |> summarise( refugees = sum(refugees, na.rm = TRUE) + sum(oip, na.rm = TRUE), .by = coo_name ) |> slice_max(order_by = refugees, n = 10) |> mutate(coo_name = str_wrap(coo_name, 25)) |> ggplot( aes( x = refugees, y = reorder(coo_name, refugees))) + geom_col( fill = unhcr_pal(n = 1, "pal_blue"), width = 0.8) + scale_x_continuous( expand = expansion(mult = c(0, .1)), breaks = seq(0, 7e6, by = 1e6), labels = scales::label_number(scale_cut = scales::cut_short_scale())) + labs( * title = "Refugees and other people in need of international protection in Peru", * subtitle = "By country of origin at the end of 2022", caption = "Source: Refugee Data Finder<br>© UNHCR, The UN Refugee Agency", x = "Number of people" ) + theme_unhcr(grid = "X", axis = "Y", axis_title = "X") ``` --- ## Elements that needs to becomes parameters.. So I will use `year` and `countryname` as my function parameters and then build and return a ggplot2 `plot` ```r *plot_top10_by_country_and_year <- function( year, * countryname) { plot <- refugees::population |> * filter(year == year & coa_name == countryname) |> summarise( refugees = sum(refugees, na.rm = TRUE) + sum(oip, na.rm = TRUE), .by = coo_name ) |> slice_max(order_by = refugees, n = 10) |> mutate(coo_name = str_wrap(coo_name, 25)) |> ggplot( aes( x = refugees, y = reorder(coo_name, refugees))) + geom_col( fill = unhcr_pal(n = 1, "pal_blue"), width = 0.8) + scale_x_continuous( expand = expansion(mult = c(0, .1)), breaks = seq(0, 7e6, by = 1e6), labels = scales::label_number(scale_cut = scales::cut_short_scale())) + labs( * title = paste0("Refugees and other people in need of international protection in ",countryname), * subtitle = paste0("By country of origin at the end of ", year), caption = "Source: Refugee Data Finder<br>© UNHCR, The UN Refugee Agency", x = "Number of people" ) + theme_unhcr(grid = "X", axis = "Y", axis_title = "X") * return(plot) } ``` --- ## let's not forget to add the documentation!!! ```r #' Create a plot with top10 country of orgin for Refugees and OIP per country of asylum and year #' #' @param year a numeric value for the year #' @param countryname the name of the country of asulum #' #' @return a ggplot2 with UNHCR brand #' #' @import unhcrthemes #' @import refugees #' @import tidyverse #' #' @examples #' plot_top10_by_country_and_year( year = 2022, #' countryname = "Peru") *plot_top10_by_country_and_year <- function( year, * countryname) { } ``` --- ## Et voila! .pull-left[ Now I can just call my function * Plotting functions can accept parameters to customize the plot. * Parameters allow you to create dynamic and flexible plots. ```r plot_top10_by_country_and_year( year = 2022, countryname = "Peru" ) ``` ] .pull-right[ <!-- --> ] --- ## Now I can share my function! .pull-left[ It becomes now easy to re-use my function in another operation.... ```r plot_top10_by_country_and_year( year = 2022, countryname = "Ecuador" ) ``` ] .pull-right[ <!-- --> ] ??? Plot Customization * Allow users to customize plots by providing parameters. * Parameters can control titles, colors, labels, etc. Organizing Plotting Functions * Create a directory or package to store your plotting functions. * Name files descriptively and include documentation. Advanced Features * Saving plots to svg or png * Creating dynamic dashboards * Integrate your plotting functions into Shiny apps for interactive visualization. --- ## How to access data - beside uisng data embedded in a package like {refugees} Through file import * from Excel file - [`readxl`](https://readxl.tidyverse.org/) * from Text file [`readr`](https://readr.tidyverse.org/) * from File generated with other statistical software using [`haven`](https://haven.tidyverse.org/) Through API * [`{activityinfo-R}`](https://www.activityinfo.org/support/docs/R/) * [`{robotoolbox}`](https://dickoa.gitlab.io/robotoolbox/), * [`{rhdx}`](http://dickoa.gitlab.io/rhdx/), * [`{riddle}`](https://edouard-legoupil.github.io/riddle/), * [`{popdata}`](https://edouard-legoupil.github.io/popdata/), --- ## Key Takeaways * Functions are essential for code re-usability and modularity. * Transition from scripts to functions provides better code organization. * Documenting functions is crucial for effective collaboration and code sharing. * Function parameters allow customization of plots. * Building a directory of plotting functions can streamlines your work. --- class: inverse, center, middle # Thank you ### Questions? [post Feedback here](https://github.com/unhcRverse/unhcrverse/issues/new?assignees=&labels=enhancement&projects=&template=comment_prex_2_tidyverse.md&title=%5Blearn%5D) -> [next you can start putting your function in a package](10.Package_Knowledge.html) <a href="index.html"><i class="fa fa-indent fa-fw fa-2x"></i></a> --- # Reference - [Build Advanced Charts in R](https://wd3.myworkday.com/unhcr/learning/course/efee8410b2b410017044140f1aeb0001?type=9882927d138b100019b928e75843018d) - [Data Wrangling in R](https://wd3.myworkday.com/unhcr/learning/course/046437bef6c810195cf76ead31590002?type=9882927d138b100019b928e75843018d) - [Code Clinic: R](https://wd3.myworkday.com/unhcr/learning/course/046437bef6c810195cfbd7b02bd90006?type=9882927d138b100019b928e75843018d) - [Coding Exercises: R Data Science](https://wd3.myworkday.com/unhcr/learning/course/046437bef6c810195cf7768256ed0000?type=9882927d138b100019b928e75843018d) - [R for Data Science](https://r4ds.had.co.nz/), - [Advanced R Programming](https://adv-r.hadley.nz/) --- # Exercise Use any chart your previously created and turn it into a function with parameters